package com.landscope.issue.exception;

import com.landscope.issue.render.Result;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.dao.CannotAcquireLockException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 异常返回处理
 *
 * @author qzp
 * @version v1.0
 * @date 2021/5/7 22:51
 **/

@ControllerAdvice
public class WebExceptionHandler {

    /**
     * 参数校验异常
     *
     * @param e:
     * @return {@link * @return java.lang.Object}
     * @throws
     * @author 瞿子朋
     * @date 2021/5/7 23:12
     * @version v1.0
     **/
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Object MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        e.printStackTrace();
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        List<ObjectError> ss = e.getBindingResult().getAllErrors();
        String field = "";
        if (ss.size() > 0) {
            ObjectError oe = ss.get(0);
            Object[] objs = oe.getArguments();
            if (objs != null && objs.length > 0) {
                field = ((DefaultMessageSourceResolvable) objs[0]).getDefaultMessage();
            }
        }
        return Result.error().code(E_EXCEPTION_TYPE.param_validated_exception.getValue())
                .message(E_EXCEPTION_TYPE.param_validated_exception.getName() + ":" + "[" + field + "]" + message).render();
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public Object HttpMessageNotReadableException(HttpMessageNotReadableException e) {
        e.printStackTrace();
        return Result.error().code(E_EXCEPTION_TYPE.param_validated_format_exception.getValue())
                .message(E_EXCEPTION_TYPE.param_validated_format_exception.getValue() + ":" + e.getMessage()).render();
    }

    /**
     * 自定义异常
     *
     * @param e:
     * @return {@link * @return java.lang.Object}
     * @throws
     * @author 瞿子朋
     * @date 2021/5/7 23:12
     * @version v1.0
     **/
    @ExceptionHandler(BizException.class)
    @ResponseBody
    public Object BizException(BizException e) {
        e.printStackTrace();
        return Result.error().code(e.getCode()).message(e.getMessage()).render();
    }

    @ExceptionHandler(CannotAcquireLockException.class)
    @ResponseBody
    public Object CannotAcquireLockException(CannotAcquireLockException e) {
        e.printStackTrace();
        return Result.error().code(E_EXCEPTION_TYPE.data_lock_timeout.getValue())
                .message(E_EXCEPTION_TYPE.data_lock_timeout.getName()).render();
    }

    /**
     * 其他异常
     *
     * @param e:
     * @return {@link * @return java.lang.Object}
     * @throws
     * @author 瞿子朋
     * @date 2021/5/7 23:12
     * @version v1.0
     **/
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object Exception(Exception e) {
        e.printStackTrace();
        StackTraceElement[] ss = e.getStackTrace();
        StringBuffer stringBuffer = new StringBuffer();
        if(e != null && e.getCause() != null)
            stringBuffer.append(e.getCause().toString());
        stringBuffer.append("\n\t    ");
        for (int i = 0; i < 5; i++) {
            StackTraceElement stackTraceElement = ss[i];
            stringBuffer.append(stackTraceElement.toString());
            stringBuffer.append("\n\t    ");
        }
        return Result.error().message(stringBuffer.toString()).render();
    }
}
